package com.olymtech.jbricks.threadpool.listener;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigFile;
import com.ctrip.framework.apollo.ConfigService;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.olymtech.jbricks.threadpool.DynamicThreadPoolManager;
import com.olymtech.jbricks.threadpool.alarm.DynamicThreadPoolAlarm;
import com.olymtech.jbricks.threadpool.config.DynamicThreadPoolProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Properties;


/**
 * Apollo配置修改监听
 *
 * @author haoting.wang
 * @date 2020/10/14 2:57 下午
 **/
@Slf4j
public class ApolloConfigUpdateListener {

    @Value("${apollo.bootstrap.namespaces:application}")
    private String namespace;

    @Autowired
    private DynamicThreadPoolManager dynamicThreadPoolManager;
    @Autowired
    private DynamicThreadPoolProperties poolProperties;

    @Autowired(required = false)
    private DynamicThreadPoolAlarm dynamicThreadPoolAlarm;

    @PostConstruct
    public void init() {
        initConfigUpdateListener();
    }

    public void initConfigUpdateListener() {
        String apolloNamespace = namespace;
        if (StringUtils.hasText(poolProperties.getApolloNamespace())) {
            apolloNamespace = poolProperties.getApolloNamespace();
        }

        String finalApolloNamespace = apolloNamespace;

        Config config = ConfigService.getConfig(finalApolloNamespace);

        config.addChangeListener(changeEvent -> {
            ConfigFileFormat configFileFormat = ConfigFileFormat.Properties;
            ConfigFile configFile = ConfigService.getConfigFile(finalApolloNamespace, configFileFormat);
            String content = configFile.getContent();

            Properties properties = convertProp(content);
            for (String key : changeEvent.changedKeys()) {
                properties.setProperty(key, changeEvent.getChange(key).getNewValue());
            }

            dynamicThreadPoolAlarm.setUpdate(true);

            poolProperties.doRefresh(properties);
            dynamicThreadPoolManager.refreshThreadPoolExecutor();

            dynamicThreadPoolAlarm.setUpdate(false);

            log.info("线程池配置有变化，刷新完成");
        });
    }


    /**
     * 刷新配置
     *
     * @param content 整个配置文件的内容
     */
    public Properties convertProp(String content) {
        Properties properties = new Properties();
        try {
            properties.load(new ByteArrayInputStream(content.getBytes()));
        } catch (IOException e) {
            log.error("转换Properties异常", e);
        }
        return properties;
    }
}
